//Copyright 2011 - Jonathan Allen

using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using Granite.Eventing;
using Granite.ComponentModel;

namespace Granite.Collections
{
	///// <summary>
	///// This is an ObservableDictionary with additional events.
	///// This will use weak events to listen to objects implementing INotifyPropertyChangedWeak.
	///// This will use normal events to listen to objects implementing INotifyPropertyChanged.
	///// </summary>
	//public class ExtendedObservableDictionary<TKey, TValue> : ObservableDictionary<TKey, TValue>, INotifyDictionaryChangedWeak, INotifyPropertyChangedWeak, INotifyItemPropertyChangedWeak, INotifyDictionaryChanged<TKey, TValue>
	//{
	//	DictionaryChangedEventManager m_DictionaryChangeEventManager;
	//	PropertyChangedEventManager m_PropertyChangedEventManager;
	//	ItemPropertyChangedEventManager m_ItemPropertyChangedEventManager;


	//	/// <summary>
	//	/// This type safe event fires after a value is added to the dictionary no matter how it is added.
	//	/// </summary>
	//	/// <remarks>Triggered by ???</remarks>
	//	public event EventHandler<ItemEventArgs<TValue>> ValueAdded;

	//	/// <summary>
	//	/// This type safe event fires after a value is removed from the dictionary no matter how it is removed.
	//	/// </summary>
	//	/// <remarks>Triggered by ???</remarks>
	//	public event EventHandler<ItemEventArgs<TValue>> ValueRemoved;

	//	/// <summary>
	//	/// This type safe event fires after a key is added to the dictionary no matter how it is added.
	//	/// </summary>
	//	/// <remarks>Triggered by ???</remarks>
	//	public event EventHandler<ItemEventArgs<TKey>> KeyAdded;

	//	/// <summary>
	//	/// This type safe event fires after a key is removed from the dictionary no matter how it is removed.
	//	/// </summary>
	//	/// <remarks>Triggered by ???</remarks>
	//	public event EventHandler<ItemEventArgs<TKey>> KeyRemoved;


	//	/// <summary>
	//	/// Adds a weak event handler
	//	/// </summary>
	//	/// <param name="eventHandler"></param>
	//	public void AddHandler(IPropertyChangedListener eventHandler)
	//	{
	//		if (m_PropertyChangedEventManager == null)
	//			m_PropertyChangedEventManager = new PropertyChangedEventManager(this);

	//		m_PropertyChangedEventManager.AddHandler(eventHandler);
	//	}

	//	/// <summary>
	//	/// Removes a weak event handler
	//	/// </summary>
	//	/// <param name="eventHandler"></param>
	//	public void RemoveHandler(IPropertyChangedListener eventHandler)
	//	{
	//		if (m_PropertyChangedEventManager != null)
	//			m_PropertyChangedEventManager.RemoveHandler(eventHandler);
	//	}

	//	/// <summary>
	//	/// Adds a weak event handler
	//	/// </summary>
	//	/// <param name="eventHandler"></param>
	//	public void AddHandler(IDictionaryChangedListener eventHandler)
	//	{
	//		if (m_DictionaryChangeEventManager == null)
	//			m_DictionaryChangeEventManager = new DictionaryChangedEventManager(this);

	//		m_DictionaryChangeEventManager.AddHandler(eventHandler);
	//	}

	//	/// <summary>
	//	/// Removes a weak event handler
	//	/// </summary>
	//	/// <param name="eventHandler"></param>
	//	public void RemoveHandler(IDictionaryChangedListener eventHandler)
	//	{
	//		if (m_DictionaryChangeEventManager != null)
	//			m_DictionaryChangeEventManager.RemoveHandler(eventHandler);
	//	}

	//	/// <summary>
	//	/// This fires after an item is removed from the collection no matter how it is removed.
	//	/// </summary>
	//	/// <param name="value"></param>
	//	/// <remarks>Triggered by SetItem, RemoveItem, and ClearItems.</remarks>
	//	protected void OnItemAdded(TValue value)
	//	{
	//		if (ValueAdded != null)
	//			ValueAdded(this, new ItemEventArgs<TValue>(value));

	//		if (m_ListeningToItemEvents)
	//		{
	//			if (value is INotifyPropertyChangedWeak)
	//				((INotifyPropertyChangedWeak)value).AddHandler(m_ItemPropertyChanged);
	//			else if (value is INotifyPropertyChanged)
	//				((INotifyPropertyChanged)value).PropertyChanged += OnItemPropertyChanged;
	//		}
	//	}

	//	/// <summary>
	//	/// This fires after an item is removed from the collection no matter how it is removed.
	//	/// </summary>
	//	/// <param name="value"></param>
	//	/// <remarks>Triggered by SetItem, RemoveItem, and ClearItems.</remarks>
	//	protected void OnItemRemoved(TValue value)
	//	{
	//		if (ValueRemoved != null)
	//			ValueRemoved(this, new ItemEventArgs<TValue>(value));

	//		if (m_ListeningToItemEvents)
	//		{
	//			if (value is INotifyPropertyChangedWeak)
	//				((INotifyPropertyChangedWeak)value).AddHandler(m_ItemPropertyChanged);
	//			else if (value is INotifyPropertyChanged)
	//				((INotifyPropertyChanged)value).PropertyChanged += OnItemPropertyChanged;

	//		}
	//	}

	//	/// <summary>
	//	/// This is called whenever an item is added to the dictionary
	//	/// </summary>
	//	/// <param name="key"></param>
	//	/// <param name="value"></param>
	//	protected override void InsertItem(TKey key, TValue value)
	//	{
	//		base.InsertItem(key, value);
	//		OnItemAdded(value);
	//		if (KeyAdded != null)
	//			KeyAdded(this, new ItemEventArgs<TKey>(key));
	//	}

	//	/// <summary>
	//	/// This is called whenever an item is removed from the dictionary
	//	/// </summary>
	//	/// <param name="key"></param>
	//	/// <param name="value"></param>
	//	protected override void RemoveItem(TKey key, TValue value)
	//	{
	//		base.RemoveItem(key, value);
	//		OnItemRemoved(value);
	//		if (KeyRemoved != null)
	//			KeyRemoved(this, new ItemEventArgs<TKey>(key));
	//	}

	//	/// <summary>
	//	/// This is called whenever an item is replaced in the dictionary
	//	/// </summary>
	//	/// <param name="key"></param>
	//	/// <param name="newValue"></param>
	//	/// <param name="oldValue"></param>
	//	protected override void SetItem(TKey key, TValue oldValue, TValue newValue)
	//	{
	//		base.SetItem(key, oldValue, newValue);
	//		OnItemRemoved(oldValue);
	//		OnItemAdded(newValue);
	//	}

	//	/// <summary>
	//	/// This is called when Clear is invoked
	//	/// </summary>
	//	protected override void ClearItems()
	//	{
	//		var temp = this.ToList();
	//		base.ClearItems();

	//		foreach (var item in temp)
	//			OnItemRemoved(item.Value);

	//		if (KeyRemoved != null)
	//			foreach (var item in temp)
	//				KeyRemoved(this, new ItemEventArgs<TKey>(item.Key));
	//	}


	//	IPropertyChangedListener m_ItemPropertyChanged;
	//	event RelayedEventHandler<PropertyChangedEventArgs> m_ItemPropertyChangedEvent;

	//	void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
	//	{
	//		if (m_ItemPropertyChangedEvent != null)
	//			m_ItemPropertyChangedEvent(this, new RelayedEventArgs<PropertyChangedEventArgs>(sender, e));
	//	}




	//	/// <summary>
	//	/// Adds a weak event handler
	//	/// </summary>
	//	/// <param name="eventHandler"></param>
	//	public void AddHandler(IItemPropertyChangedListener eventHandler)
	//	{
	//		if (m_ItemPropertyChangedEventManager == null)
	//		{
	//			m_ItemPropertyChangedEventManager = new ItemPropertyChangedEventManager(this);
	//			ListenToEvents();
	//		}

	//		m_ItemPropertyChangedEventManager.AddHandler(eventHandler);
	//	}

	//	/// <summary>
	//	/// Removes a weak event handler
	//	/// </summary>
	//	/// <param name="eventHandler"></param>
	//	public void RemoveHandler(IItemPropertyChangedListener eventHandler)
	//	{
	//		if (m_ItemPropertyChangedEventManager != null)
	//			m_ItemPropertyChangedEventManager.RemoveHandler(eventHandler);
	//	}


	//	/// <summary>
	//	/// When someone attaches to the ItemPropertyChanged event this is set to true and we start listening for change notifications.
	//	/// </summary>
	//	private bool m_ListeningToItemEvents;

	//	/// <summary>
	//	/// This enables the ItemPropertyChanged events. 
	//	/// </summary>
	//	private void ListenToEvents()
	//	{
	//		if (m_ListeningToItemEvents)
	//			return;

	//		m_ItemPropertyChanged = new PropertyChangedListener(OnItemPropertyChanged);
	//		foreach (var item in this.Values.OfType<INotifyPropertyChanged>())
	//		{
	//			if (item is INotifyPropertyChangedWeak)
	//				((INotifyPropertyChangedWeak)item).AddHandler(m_ItemPropertyChanged);
	//			else
	//				item.PropertyChanged += OnItemPropertyChanged;
	//		}


	//		m_ListeningToItemEvents = true;
	//	}

	//	/// <summary>
	//	/// Use this event to listen for changes to properties on items contained by this collection without having to explicitly attach an event handler to each item.
	//	/// </summary>
	//	public event RelayedEventHandler<PropertyChangedEventArgs> ItemPropertyChanged
	//	{
	//		add
	//		{
	//			ListenToEvents();
	//			m_ItemPropertyChangedEvent += value;
	//		}
	//		remove { m_ItemPropertyChangedEvent -= value; }
	//	}
	//}
}
